package com.yanqu.road.server.gameplayer.module.activity.orewar;

import com.yanqu.road.entity.activity.*;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.logic.bussiness.player.UserActivityBussiness;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.pb.commonactivity.CommonActivityProto;
import com.yanqu.road.pb.cross.activity.CrossActivityProto;
import com.yanqu.road.pb.crossunion.activity.CrossUnionActivityRankDataProto;
import com.yanqu.road.pb.orewaractivity.OreWarActivityProto;
import com.yanqu.road.pb.rank.YRankProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.banquet.BanquetModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.DecorationModule;
import com.yanqu.road.server.logic.activity.orewar.OreWarActivityData;
import com.yanqu.road.server.logic.activity.orewar.condition.BaseOreWarActivityCondition;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.orewar.OreWarActivityMgr;
import com.yanqu.road.server.manger.activity.orewar.OreWarActivityRankMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.manger.union.UnionActivityMgr;
import com.yanqu.road.server.pb.OreWarActivityPb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class OreWarActivityModule extends GeneralModule {

    //activityId type OreWarActivityData
    private Map<Integer, Map<Integer, OreWarActivityData>> activityDataMap;

    public OreWarActivityModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        //换到mgr去保存
        /*for(Map<Integer, OreWarActivityData> dataMap : activityDataMap.values()) {
            for (OreWarActivityData activityData : dataMap.values()) {
                for (UserActivityConditionData conditionData : activityData.getUserActivityConditionDataList()) {
                    if (conditionData.isInsertOption()) {
                        UserOreWarActivityBussiness.addUserActivityConditionData(conditionData);
                    } else if (conditionData.isUpdateOption()) {
                        UserOreWarActivityBussiness.updateUserActivityConditionData(conditionData);
                    }
                }
            }
        }*/
        return true;
    }

    @Override
    public boolean loadData() {
        activityDataMap = new ConcurrentHashMap<>();
        List<ActivityInfo> activityInfoList = OreWarActivityMgr.getOpenActivityInfoList();
        for(ActivityInfo activityInfo : activityInfoList){
            Map<Integer, List<UserActivityConditionData>> userActivityConditionDataMap = OreWarActivityMgr.getUserActivityConditionDataMap(player.getUserId(),activityInfo.getActivityId());
            if (null != userActivityConditionDataMap) {
                for (Map.Entry<Integer, List<UserActivityConditionData>> dataEntry : userActivityConditionDataMap.entrySet()) {
                    addActivity(activityInfo, dataEntry.getValue(), dataEntry.getKey(), false);
                }
            }
        }
        addNewActivity();
        return true;
    }

    @Override
    public void loginSendMsg() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.OreWar.getValue())) {
            addNewActivity();
        }

    }

    @Override
    public void afterLogin() {
        syncActivity();
    }

    public void initOreWarSystem() {
        syncActivity();
    }

    public void syncActivity(){
        Map<Integer, Map<Integer, OreWarActivityData>> dataMap = new ConcurrentHashMap<>();
        List<ActivityInfo> activityInfoList = OreWarActivityMgr.getOpenActivityInfoList();
        if(activityInfoList.size() > 0){
            for (ActivityInfo activityInfo : activityInfoList) {
                Map<Integer, OreWarActivityData> tempMap = activityDataMap.get(activityInfo.getActivityId());
                if (null != tempMap) {
                    dataMap.put(activityInfo.getActivityId(), tempMap);
                }
            }
            OreWarActivityProto.OreWarActivityDetailMsg.Builder detailMsg = OreWarActivityMgr.getOreWarActivityDetailMsg(getUserId(),dataMap, player.getLanguage());
            player.sendPacket(Protocol.U_ORE_WAR_ACTIVITY_DETAIL, detailMsg);
        }
    }

    public void addNewActivity() {
        synchronized (this) {
            List<ActivityInfo> activityInfoList = OreWarActivityMgr.getOpenActivityInfoList();
            for (ActivityInfo activityInfo : activityInfoList) {
                Map<Integer, List<ActivityConditionInfo>> dataMap = OreWarActivityMgr.getActivityConditionInfoMap(activityInfo.getActivityId());
                if (null != dataMap) {
                    for (int type : dataMap.keySet()) {
                        addActivity(activityInfo, new ArrayList<>(), type, true);
                    }
                }
                Map<Integer, OreWarActivityData> tempActivityDataMap = getActivityDataMap(activityInfo.getActivityId());
                if (null != tempActivityDataMap) {
                    for (OreWarActivityData activityData : tempActivityDataMap.values()) {
                        for (BaseOreWarActivityCondition baseActivityCondition : activityData.getBaseActivityConditionList()) {
                            if (null != baseActivityCondition) {
                                baseActivityCondition.initValue();
                            }
                        }
                    }
                }
            }
        }
    }

    private Map<Integer, OreWarActivityData> getActivityDataMap(int activityId){
        return activityDataMap.get(activityId);
    }

    private void addActivity(ActivityInfo activityInfo, List<UserActivityConditionData> conditionDataList, int type, boolean isNew) {
        synchronized (this) {
            if (null != activityInfo) {
                if (!activityDataMap.containsKey(activityInfo.getActivityId())) {
                    activityDataMap.put(activityInfo.getActivityId(), new ConcurrentHashMap<>());
                }

                Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(activityInfo.getActivityId());
                if (dataMap.containsKey(type)) {
                    return;
                }
                List<ActivityConditionInfo> conditionInfoList = OreWarActivityMgr.getActivityConditionInfoList(activityInfo.getActivityId(), type);
                if (null == conditionInfoList) {
                    return;
                }

                OreWarActivityData activityData = new OreWarActivityData(player, activityInfo, conditionDataList);
                for (ActivityConditionInfo conditionInfo : conditionInfoList) {
                    if (activityData.continueAdd(conditionInfo.getType())) {
                        BaseOreWarActivityCondition baseActivityCondition = BaseOreWarActivityCondition.createActivityCondition(player, activityData, activityInfo, conditionInfo);
                        if (null != baseActivityCondition) {
                            activityData.addCondition(baseActivityCondition);
                            if (isNew) {
                                UserActivityConditionData userConditionData = ActivityMgr.initUserActivityConditionData(player, conditionInfo);
                                activityData.addUserActivityConditionData(userConditionData);
                                //Mgr中添加
                                OreWarActivityMgr.addUserActivityConditionData(getUserId(), userConditionData);
                            }
                        }
                    }
                }
                dataMap.put(type, activityData);
                activityData.addToPlayer();
            }
        }
    }

    public ActivityRewardResult getRankReward(int activityId, int type) {
        ActivityRewardResult result = new ActivityRewardResult();
        ActivityInfo openActivityInfo = OreWarActivityMgr.getOpenActivityInfo(activityId);
        if(null == openActivityInfo){
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_NO_IN_TIME);
            return result;
        }
        Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(openActivityInfo.getActivityId());
        if(null == dataMap){
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_NO_IN_TIME);
            return result;
        }
        OreWarActivityData activityData = dataMap.get(type);
        if (null == activityData) {
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_NO_IN_TIME);
            return result;
        }
        if(!ActivityMgr.activityInRewardPeriod(openActivityInfo)){
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_NO_IN_REWARD_TIME);
            return result;
        }
        if(!ActivityMgr.activityInCanRewardPeriod(openActivityInfo)){
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_REWARD_SETTLEMENT_TIME);
            return result;
        }
        UserActivityConditionData conditionData = activityData.getFirstConditionData();
        if(null == conditionData){
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_NO_JOIN);
            return result;
        }
        if (conditionData.isGetReward()) {
            result.setRet(GameErrorCode.E_ORE_ACTIVITY_HAS_GET_REWARD);
            return result;
        }
        int myRank;
        boolean isMaster = false;
        UnionActivityConditionData unionActivityConditionData = null;
        if(OreWarActivityMgr.CONDITION_TYPE_USER == type) {
            myRank = OreWarActivityRankMgr.getActivityRank(openActivityInfo.getActivityId(), player.getUserId());
        }else {
            unionActivityConditionData = OreWarActivityRankMgr.getUnionActivityConditionData(activityId, player.getUserId());
            if(null == unionActivityConditionData){
                result.setRet(GameErrorCode.E_ORE_ACTIVITY_NO_JOIN);
                return result;
            }
            myRank = OreWarActivityRankMgr.getActivityUnionRank(openActivityInfo.getActivityId(), unionActivityConditionData.getUnionUid());
            isMaster = (unionActivityConditionData.getUnionBaseInfo().getMasterUserId() == player.getUserId());
        }
        ActivityConditionInfo conditionInfo = OreWarActivityMgr.getActivityConditionInfoByRank(activityId, type, myRank);
        if (conditionInfo != null) {// 添加奖励
            if(isMaster && OreWarActivityMgr.CONDITION_TYPE_UNION == type){
                player.getModule(CurrencyModule.class).addCurrency(conditionInfo.getMasterReward(), eLogMoneyType.Activity, eLogMoneyType.OreWarActivityUnionRankReward);
                result.setReward(conditionInfo.getMasterRewardStr());
            }else {
                if(OreWarActivityMgr.CONDITION_TYPE_UNION == type) {
                    result.setReward(UnionActivityMgr.getUnionMemberPositionDataReward(unionActivityConditionData,conditionInfo,player.getUserId()));
                    player.getModule(CurrencyModule.class).addCurrency(result.getReward(), eLogMoneyType.Activity, eLogMoneyType.OreWarActivityUnionRankReward);
                }else {
                    player.getModule(CurrencyModule.class).addCurrency(conditionInfo.getReward(), eLogMoneyType.Activity, eLogMoneyType.OreWarActivityRankReward);
                    result.setReward(conditionInfo.getRewardStr());
                }
            }
        }
        conditionData.setGetReward(true);
        onActivityDataChange(activityData);
        activityData.finish(conditionData.getConditionId());

        LogMgr.addLogOreWarActivityRankReward(player.getUserId(), activityId, type, myRank, result.getReward());
        return result;
    }


    private int checkGetReward(int activityId,int type){
        ActivityInfo openActivityInfo = OreWarActivityMgr.getOpenActivityInfo(activityId);
        if(null == openActivityInfo){
            return GameErrorCode.E_ORE_ACTIVITY_NO_IN_TIME;
        }
        Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(openActivityInfo.getActivityId());
        if(null == dataMap){
            return GameErrorCode.E_ORE_ACTIVITY_NO_IN_TIME;
        }
        OreWarActivityData activityData = dataMap.get(type);
        if (null == activityData) {
            return GameErrorCode.E_ORE_ACTIVITY_NO_IN_TIME;
        }
        if(!ActivityMgr.activityInRewardPeriod(openActivityInfo)){
            return GameErrorCode.E_ORE_ACTIVITY_NO_IN_REWARD_TIME;
        }
        if(!ActivityMgr.activityInCanRewardPeriod(openActivityInfo)){
            return GameErrorCode.E_ORE_ACTIVITY_REWARD_SETTLEMENT_TIME;
        }
        UserActivityConditionData conditionData = activityData.getFirstConditionData();
        if(null == conditionData){
            return GameErrorCode.E_ORE_ACTIVITY_NO_JOIN;
        }
        if (conditionData.isGetReward()) {
            return GameErrorCode.E_ORE_ACTIVITY_HAS_GET_REWARD;
        }
        return 0;
    }
    public ActivityRewardResult sendNewCrossRankReward(int activityId,int conditionId, int type) {
        ActivityRewardResult result = new ActivityRewardResult();
        int ret = checkGetReward(activityId,type);
        if(ret != 0){
            result.setRet(ret);
            return result;
        }
        ActivityConditionInfo activityConditionInfo = OreWarActivityMgr.getActivityConditionInfo(activityId, conditionId);
        Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(activityId);
        OreWarActivityData activityData = dataMap.get(activityConditionInfo.getType());
        UserActivityConditionData conditionData = activityData.getFirstConditionData();
        String unionUid = "";
        if (activityConditionInfo.getType() == OreWarActivityMgr.CONDITION_TYPE_USER) {
            YRankProto.YRankReqMsg.Builder builder = YRankProto.YRankReqMsg.newBuilder();
            builder.setActivityId(activityId);
            builder.setGroupId(GameUnionActivityGroupMgr.getGroupId(activityId, player.getUserId()));
            builder.setIdKey(String.valueOf(activityConditionInfo.getType()));
            builder.setRewardConditionId(conditionId);
            player.sendUnionActivityGroupPacket(CrossProtocol.C2_CROSS_YRANK_GET_USER_RANK_TO_REWARD, builder, activityId);
            return result;
        } else if (activityConditionInfo.getType() == OreWarActivityMgr.CONDITION_TYPE_UNION) {
            YRankProto.YRankReqMsg.Builder builder = YRankProto.YRankReqMsg.newBuilder();
            builder.setActivityId(activityId);
            builder.setGroupId(GameUnionActivityGroupMgr.getGroupId(activityId, player.getUserId()));
            builder.setIdKey(String.valueOf(activityConditionInfo.getType()));
            builder.setRewardConditionId(conditionId);
            player.sendUnionActivityGroupPacket(CrossProtocol.C2_CROSS_YRANK_GET_UNION_RANK_TO_REWARD, builder, activityId);
            return result;
        }
        //发送请求到跨服获取排名
        CrossActivityProto.CrossActivityGetRewardReqMsg.Builder reqMsg = CrossActivityProto.CrossActivityGetRewardReqMsg.newBuilder();
        reqMsg.setActivityId(activityId);
        reqMsg.setConditionId(conditionData.getConditionId());
        reqMsg.setUnionUid(unionUid);
        YanQuMessage pkg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_OREWAR_GET_RANK_REWARD, reqMsg);
        GamePlayerMgr.sendPacket(player.getUserId(), pkg);
        return result;
    }


    public ActivityRewardResult sendCrossRankReward(int activityId,int conditionId, int type) {
        ActivityRewardResult result = new ActivityRewardResult();
        int ret = checkGetReward(activityId,type);
        if(ret != 0){
            result.setRet(ret);
            return result;
        }
        ActivityConditionInfo activityConditionInfo = OreWarActivityMgr.getActivityConditionInfo(activityId, conditionId);
        Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(activityId);
        OreWarActivityData activityData = dataMap.get(activityConditionInfo.getType());
        UserActivityConditionData conditionData = activityData.getFirstConditionData();
        String unionUid = "";
        if(activityConditionInfo.getType() == OreWarActivityMgr.CONDITION_TYPE_UNION) {
          /*  CrossActivityProto.CrossActivityGetRewardReqMsg.Builder reqMsg = CrossActivityProto.CrossActivityGetRewardReqMsg.newBuilder();
            reqMsg.setActivityId(activityId);
            reqMsg.setConditionId(conditionData.getConditionId());
            reqMsg.setUnionUid(unionUid);
            YanQuMessage pkg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_OREWAR_GET_RANK_REWARD, reqMsg);
            GamePlayerMgr.sendChannelPacket(player.getUserId(), pkg);*/
            CrossUnionActivityRankDataProto.CrossUnionActivityGetRewardReqMsg.Builder reqMsg = CrossUnionActivityRankDataProto.CrossUnionActivityGetRewardReqMsg.newBuilder();
            reqMsg.setActivityId(activityId);
            reqMsg.setConditionType(type);
            reqMsg.setConditionId(conditionId);
            reqMsg.setRankType(3);
            player.sendPacket(CrossProtocol.C_CROSS_UNION_ACTIVITY_RANK_REWARD, reqMsg);
            return result;
        }
        //发送请求到跨服获取排名
        CrossActivityProto.CrossActivityGetRewardReqMsg.Builder reqMsg = CrossActivityProto.CrossActivityGetRewardReqMsg.newBuilder();
        reqMsg.setActivityId(activityId);
        reqMsg.setConditionId(conditionData.getConditionId());
        reqMsg.setUnionUid(unionUid);
        YanQuMessage pkg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_OREWAR_GET_RANK_REWARD, reqMsg);
        GamePlayerMgr.sendPacket(player.getUserId(), pkg);
        return result;
    }

    public ActivityRewardResult getCrossRankReward(int activityId, int conditionId, int myRank, int position) {
        ActivityRewardResult result = new ActivityRewardResult();
        ActivityInfo activityInfo = OreWarActivityMgr.getOpenActivityInfo(activityId);
        ActivityConditionInfo activityConditionInfo = OreWarActivityMgr.getActivityConditionInfo(activityId, conditionId);
        Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(activityId);
        OreWarActivityData activityData = dataMap.get(activityConditionInfo.getType());
        UserActivityConditionData conditionData = activityData.getFirstConditionData();
        ActivityConditionInfo conditionInfo = OreWarActivityMgr.getActivityConditionInfoByRank(activityId, activityConditionInfo.getType(), myRank);
        if(null == conditionInfo) {
            result.setRet(GameErrorCode.E_ACTIVITY_CONDITION_NO_COMPLETE);
            return result;
        }
        if(null == conditionData || conditionData.isGetReward()){
            result.setRet(GameErrorCode.E_ACTIVITY_REWARD_IS_GET);
            return result;
        }
        if(OreWarActivityMgr.CONDITION_TYPE_UNION == conditionInfo.getType()) {
            //根据职位获取奖励
            result.setReward(UnionActivityMgr.getUnionMemberPositionDataReward(position,conditionInfo,player.getUserId()));
            player.getModule(CurrencyModule.class).addCurrency(result.getReward(), eLogMoneyType.Activity, eLogMoneyType.CrossOreWarActivityUnionRankReward);

        }else {
            player.getModule(CurrencyModule.class).addCurrency(conditionInfo.getReward(), eLogMoneyType.Activity, eLogMoneyType.CrossOreWarActivityRankReward);
            result.setReward(conditionInfo.getRewardStr());
        }
        conditionData.setGetReward(true);
        onActivityDataChange(activityData);
        activityData.finish(conditionData.getConditionId());

        String rewardStr = result.getReward();
        if (rewardStr != null) {
            Property property = PropertyHelper.parseStringToProperty(rewardStr);
            if (property != null) {
                //记录跨服称号包含的区服id
                property.getGoods().forEach((k,v)->{
                    if (GoodsMgr.isDecorationGoods(k)) {
                        player.getModule(DecorationModule.class).setServerIds(k, activityInfo.getActivityId(), activityInfo.getServerListStr());
                    }
                });
                player.getModule(BanquetModule.class).getCrossBanquetInvitationReward(rewardStr,activityInfo.getServerListStr());
            }
        }

        LogMgr.addLogActivityReward(player.getUserId(), activityId, activityInfo.getType(), activityInfo.getChildType(),
                activityConditionInfo.getConditionId(), myRank, false, result.getReward());
        return result;
    }

    //同步到活动中的condition改名
    public void nickNameChange(){
        List<ActivityInfo> activityInfoList = OreWarActivityMgr.getOpenActivityInfoList();
        if(activityInfoList.size() > 0) {
            for(ActivityInfo activityInfo : activityInfoList){
                Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(activityInfo.getActivityId());
                if(null != dataMap) {
                    OreWarActivityData activityData = dataMap.get(OreWarActivityMgr.CONDITION_TYPE_UNION);
                    if(null != activityData){
                        List<UserActivityConditionData> dataList = activityData.getUserActivityConditionDataList();

                    }
                }
            }

        }
    }

    public void onActivityDataChange(OreWarActivityData activityData){
        CommonActivityProto.CommonActivityDataMsg.Builder dataMsg = OreWarActivityPb.parseCommonActivityDataMsg(activityData);
        if(null != dataMsg) {
            player.sendPacket(Protocol.U_ORE_WAR_ACTIVITY_DATA_SYNC, dataMsg);
        }
    }

    public UserActivityConditionData getUserActivityConditionData(int activityId){
        Map<Integer, OreWarActivityData> dataMap = activityDataMap.get(activityId);
        if(null != dataMap){
            OreWarActivityData activityData = dataMap.get(OreWarActivityMgr.CONDITION_TYPE_UNION);
            if(null != activityData){
                return activityData.getFirstConditionData();
            }
        }
        return null;
    }
}
